#pragma once
#ifndef _FEM_SUBDOMAIN_
#define _FEM_SUBDOMAIN_

//============================================================================================================================
//============================================================================================================================
// QtCore
#include <QtCore/QList>
// Локальные
#include "core_global.h"

//============================================================================================================================
//============================================================================================================================
namespace fem
{
    /// Подобласть расчетной области.
    //
    /// Подобласть пространства ограниченная замкнутой ломаной. Причем каждому сегменту подобласти должно быть назначено некоторое
    /// краевое условие, а сама подобласть должна быть ассоциирована с некоторым материалом.
    /// \remarks Корректная работа алгоритма триангуляции гарантируется только для выпуклых подобластей. Но в ряде случаев
    /// алгоритм может отработать корректно и для невыпуклой подобласти.
    class CORE_EXPORT Subdomain
    {
    public:
        /// Создание подобласти расчётной области.
        /// \param border_segments Список сегментов, составляющих ломаную ограничивающую подобласть.
        /// \param material Идентификатор материала, соответствующего подобласти.
        Subdomain(const QList<int> &border_segments, int material) :
          m_Material(material), m_IsTriangulated(false), m_BorderSegments(border_segments) {}

        /// Отметить область как триангулированную/нетриангулированную.
        void setTriangulated(bool triangulated) {m_IsTriangulated = triangulated;}

        /// Получить информацию о том, триангулирована ли подобласть.
        bool triangulated() const {return m_IsTriangulated;}

        /// Получение идентификатор материала, соответствующего подобласти.
        int material() const {return m_Material;}

        /// Функция позволяет узнать глобальный номер сегмента границы(номер сегмента во всем наборе сегментов границ расчетной области)
        /// по локальному номеру сегмента границы(номер сегмента границы в наборе сегментов границы, ограничивающих подобласть).
        int borderSegment(int index) const
        {
            Q_ASSERT_X(index >= 0, "Subdomain::borderSegment", "index is below zero");
            Q_ASSERT_X(index <= m_BorderSegments.size(), "Subdomain::borderSegment", "index is more than count of border segments");
            return m_BorderSegments[index];
        }

        /// Переупорядочить список сегментов, ограничивающих подобласть.
        //
        /// В некоторых ситуациях смена локальной нумерации сегментов, ограничивающих подобласть, позволяет значительно упростить
        /// алгоритм триангуляции подобласти. В частности, это позволяет убрать ряд проверок и ветвлений алгоритма.
        /// \param new_segment_indices i-й элемент списка, указывает какой элемент старого списка сегментов должен стать
        /// i-м элементом нового списка сегментов.
        void reorderBorderSegments(const QList<int> &new_segment_indices);

    private:
        int m_Material;                 ///< Идентификатор материала, соответствующего подобласти.
        bool m_IsTriangulated;          ///< Флаг, показывающий была ли триангулирована подобласть.
        QList<int> m_BorderSegments;    ///< Список сегментов, составляющих ломаную ограничивающую подобласть.
    };
}

#endif // _FEM_SUBDOMAIN_
